package com.ethanzzh.ethanzzh_xdclass.service;

import com.ethanzzh.ethanzzh_xdclass.config.WeChatConfig;
import com.ethanzzh.ethanzzh_xdclass.dto.VideoOrderDTO;
import com.ethanzzh.ethanzzh_xdclass.mapper.UserMapper;
import com.ethanzzh.ethanzzh_xdclass.mapper.VideoMapper;
import com.ethanzzh.ethanzzh_xdclass.mapper.VideoOrderMapper;
import com.ethanzzh.ethanzzh_xdclass.model.pojo.User;
import com.ethanzzh.ethanzzh_xdclass.model.pojo.Video;
import com.ethanzzh.ethanzzh_xdclass.model.pojo.VideoOrder;
import com.ethanzzh.ethanzzh_xdclass.utils.CommonUtils;
import com.ethanzzh.ethanzzh_xdclass.utils.HttpUtils;
import com.ethanzzh.ethanzzh_xdclass.utils.WXPayUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Service
public class VideoOrderService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private Logger dataLogger = LoggerFactory.getLogger("dataLogger");


    @Autowired
    private WeChatConfig weChatConfig;

    @Autowired
    private VideoOrderMapper videoOrderMapper;

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private UserMapper userMapper;



    @Transactional(propagation = Propagation.REQUIRED)
    public String save(VideoOrderDTO videoOrderDTO) throws Exception {
        //日志计数器
        dataLogger.info("module=video_order`api=save`user_id={}`video_id={}", videoOrderDTO.getUserId(),videoOrderDTO.getVideoId());

        //查找视频信息
        Video video = videoMapper.selectByPrimaryKey(videoOrderDTO.getVideoId());
        //查找用户信息
        User user = userMapper.selectByPrimaryKey(videoOrderDTO.getUserId());

        //生成订单
        VideoOrder videoOrder = new VideoOrder();
        videoOrder.setTotalFee(video.getPrice());
        videoOrder.setVideoImg(video.getCoverImg());
        videoOrder.setVideoTitle(video.getTitle());
        videoOrder.setCreateTime(new Date());
        videoOrder.setVideoId(video.getId());
        videoOrder.setState(0);
        videoOrder.setUserId(user.getId());
        videoOrder.setHeadImg(user.getHeadImg());
        videoOrder.setNickname(user.getName());

        videoOrder.setDel(0);
        videoOrder.setIp(videoOrderDTO.getIp());
        videoOrder.setOutTradeNo(CommonUtils.generateUUID());
        videoOrderMapper.insertSelective(videoOrder);

        //调统一下单api 获取codeurl
        String codeUrl = unifiedOrder(videoOrder);

        return codeUrl;
    }

    /**
     * 统一下单方法
     *
     * @return
     */
    private String unifiedOrder(VideoOrder videoOrder) throws Exception {
        //1、生成签名
        SortedMap<String, String> params = new TreeMap<>();
        params.put("appid", weChatConfig.getAppId());
        params.put("mch_id", weChatConfig.getMchId());
        params.put("nonce_str", CommonUtils.generateUUID());
        params.put("body", videoOrder.getVideoTitle());
        params.put("out_trade_no", videoOrder.getOutTradeNo());
        params.put("total_fee", videoOrder.getTotalFee().toString());
        params.put("spbill_create_ip", videoOrder.getIp());
        params.put("notify_url", weChatConfig.getPayCallbackUrl());
        params.put("trade_type", "NATIVE");
        //2、生成sign签名
        String sign = WXPayUtil.createSign(params, weChatConfig.getKey());
        //3、全部放入SortedMap中 自动按照ASCII码从小到大排序
        params.put("sign", sign);

        //4、将map（params） 转xml
        String payXml = WXPayUtil.mapToXml(params);
        //5、统一下单 返回params里面的所有参数 另外加一个code_url
        String orderStr = HttpUtils.doPost(WeChatConfig.getUnifiedOrderUrl(), payXml, 4000);
        if (orderStr == null) {
            return null;
        }
        //6、转化为map 从中拿到code_url 返回
        Map<String, String> unifiedOrderMap = WXPayUtil.xmlToMap(orderStr);
        System.out.println(unifiedOrderMap.toString());
        if (unifiedOrderMap != null) {
            return unifiedOrderMap.get("code_url");
        }
        return null;
    }

    public VideoOrder findOutTradeNo(String outTradeNo) {
       return videoOrderMapper.findByOutTradeNo(outTradeNo);
    }

    public int updateVideoOrderByOutTradeNo(VideoOrder videoOrder) {
        return videoOrderMapper.updateVideoOrderByOutTradeNo(videoOrder);
    }


}
